package com.zetor.ms.application.service.base.impl;

import com.zetor.ms.application.adapter.ISeataAdapter;
import com.zetor.ms.application.service.base.ITransactionService;
import com.zetor.ms.core.sequence.SnowflakeIdWorker;
import com.zetor.ms.core.util.*;
import com.zetor.ms.repository.entity.mybatisplus.DemoUserEntity;
import com.zetor.ms.repository.entity.poeorder.BillDetailEntity;
import com.zetor.ms.repository.mapper.mybatisplus.DemoUserMapper;
import com.zetor.ms.repository.mapper.poeorder.BillDetailMapper;
import com.zetor.ms.repository.mapper.poeorder.OdsBookHeadMapper;
import io.seata.core.context.RootContext;
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.sql.Timestamp;

/**
 * 事务回滚 demo service
 *
 * @author zlc
 * @date 2021/11/05
 */

@Service
public class TransactionServiceImpl implements ITransactionService {
    @Resource
    private SnowflakeIdWorker snowflakeIdWorker;
    @Autowired
    private DemoUserMapper demoUserMapper;
    @Autowired
    private BillDetailMapper bDetailMapper;
    @Autowired
    private OdsBookHeadMapper odsHeaderMapper;
    @Autowired
    private ISeataAdapter demoSeataAdapter;

    /**
     * 分布式事务, seata, 2 app
     * @return
     */
    @Override
    @GlobalTransactional(name = "seata-save-order",rollbackFor = Exception.class)
    public String seataCaseOne() {
        // 本地保存操作
        DemoUserEntity user = new DemoUserEntity();
        user.setId(snowflakeIdWorker.nextId());
        user.setAge(1);
        user.setName("seata_order");
        user.setEmail("seata_order@mail.com");
        LogUtils.info("----->开始新建用户");
        demoUserMapper.insert(user);
        // 远程事务
        LogUtils.info("----->开始新建订单");
        LogUtils.info("XID:" + RootContext.getXID());

        Long orderId = demoSeataAdapter.seataBCase1();
        if (orderId == null || orderId.equals(0L)) {
            return "error.qry.feign.failed";
        }
        // CASE1: A exception
//        int i = 1 / 0;
        return "info.logic.success";
    }


    /**
     * 分布式事务，seata, 3 app
     * @return
     */
    @Override
    @GlobalTransactional(name = "seata-save-order-stock",rollbackFor = Exception.class)
    public String seataCaseTwo() {
        // 本地保存操作
        DemoUserEntity user = new DemoUserEntity();
        user.setId(snowflakeIdWorker.nextId());
        user.setAge(1);
        user.setName("seata_order");
        user.setEmail("seata_order@mail.com");
        LogUtils.info("----->开始新建用户");
        demoUserMapper.insert(user);
        // 远程事务 case4
        LogUtils.info("XID:" + RootContext.getXID());
        Long orderId = demoSeataAdapter.seataBCase2();
        if (orderId == null || orderId.equals(0L)) {
            return "error.qry.feign.failed";
        }
        //注释分支处理
        // 远程事务
//        LogUtils.info("XID:" + RootContext.getXID());
//        Long orderId = demoSeataAdapter.seataBCase1();
//        if (orderId == null || orderId.equals(0L)) {
//            return "error.qry.feign.failed";
//        }
//        // 远程事务
//        Long stockId = demoSeataAdapter.seataCCase4(orderId);
//        if (stockId == null || stockId.equals(0L)) {
//            return "error.qry.feign.failed";
//        }
        return "info.logic.success";
    }


    /**
     * 分布式事务，seata
     * @return
     */
    @Override
    @GlobalTransactional(name = "seata-biz-spd",rollbackFor = Exception.class)
    public String seataCaseThree() {
        LogUtils.info("XID:" + RootContext.getXID());
        // 保存账单明细 opo.fin_opf_billdetail
        BillDetailEntity detail = new BillDetailEntity();
        detail.setBillSn(snowflakeIdWorker.getStrId());
        detail.setHospitalId("h001");
        detail.setCompoundId("c001");
        detail.setTransType("1");
        detail.setRegSn("regSn");
        detail.setRecipeNo("reno");
        detail.setSortNo(new BigDecimal(10));
        detail.setSeeSn("seeSn");

        detail.setPatientId("pid");
        detail.setItemCode("exec");
        detail.setItemName("exec");
        detail.setUnitPrice(new BigDecimal(1));
        detail.setFeeCode("feecode");

        detail.setDrugFlag("1");
        detail.setChargeQty(new BigDecimal(1));
        detail.setExecDeptCode("code");
        detail.setExecDeptName("name");
        detail.setPayFlag("1");
        detail.setValidState("1");
        detail.setChargeOperCode("ocode");
        detail.setChargeDatetime(new Timestamp(System.currentTimeMillis()));

        detail.setBillSourceClass("1");
        detail.setOperCode("code");
        detail.setOperDatetime(new Timestamp(System.currentTimeMillis()));
        LogUtils.info("----->开始新建用户");
        bDetailMapper.insert(detail);
        // 更新订单头表为接单 opo.ods_book_out_head book_state
        odsHeaderMapper.uptBookState("2", "BK202010230000000003");

        // 调用 spd 进行获取价格并插入预扣spd.PHA_DS_DRUG_BOOK
        Long orderId = demoSeataAdapter.seataSpdCase3();
        if (orderId == null || orderId.equals(0L)) {
            return "error.qry.feign.failed";
        }
        return "info.logic.success";
    }
}
